package com.ruixinzheng.kotlindemo.grammar

import android.view.View
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainCoroutineDispatcher
import kotlin.coroutines.CoroutineContext

fun main() {
    InitOrderDemo("John")
}

fun basicType() {  // 返回类型是Unit代表没有返回值，相当于java的void
    val array = arrayOf(1, 2, 3) // 数组
    val array2 = arrayOfNulls<Int>(3)

    val i = 3; // 自动推断类型为Int
    if (i is Any) {} // is判断实例的类型，所有kotlin类的基类都是Any
    val context:CoroutineContext = Dispatchers.Main
    val main = context as MainCoroutineDispatcher // 使用as强制转换类型
}

// 控制流程
fun controlFlow() {
    var a = 1
    val b = 2
    val max = if (a > b) a else b // if作为三元运算符

    when (max) {
        1 -> print("x == 1")
        2 -> print("x == 2")
        else -> {
            print("x is neither 1 nor 2")
        }
    }

    for (i in 1..3) {
        println(i)
    }

    while (a > 0) {
        a--
    }

    do {
        a--
    } while (a > 0)

    // Kotlin 中所有异常类继承自 Throwable 类
    try {
        throw Exception("Hello")
    } catch (e: Exception) {
    } finally {
    }
}

fun clsAndObject() {
    // 对象表达式
    val helloWorld = object {
        val hello = "Hello"
        val world = "World"
        // object expressions extend Any, so `override` is required on `toString()`
        override fun toString() = "$hello $world"
    }
    val listener = View.OnClickListener {}  // 若接口类只有一个未实现的函数时可以用lambda表达式来创建实例
    val listener2 = object : View.OnAttachStateChangeListener {
        override fun onViewAttachedToWindow(v: View) {}
        override fun onViewDetachedFromWindow(v: View) {}
    }
    val factory = object : ViewModelProvider.Factory {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return super.create(modelClass)
        }
    }

    fun getObject() = object {
        val x: String = "x"
    }
    println(getObject().x)
}

/*
类可以包含：主构造函数 次构造函数 初始化块 属性 函数 嵌套类与内部类 对象声明
 */
// 主构造函数里若参数前加val或var表示声明属性
class Person(val name: String, val age: Int) {  // 这里的主构造函数省略了关键字constructor

    // 次构造器
    constructor(name: String) : this(name, 1) {
    }
    companion object { // 一个类只能有一个伴生对象
        fun create(name: String, age: Int):Person {
            return Person(name, age)
        }
    }
}

abstract class Polygon {
    abstract fun draw()
}

// 编译器会自动给它添加 toString() equals() hashCode()
data class DataCls(val i:Int) {}

// 对象声明，相当于单实例
object DataProviderManager {
    fun registerDataProvider() {}
}

// 编译器会自动给它添加 toString() equals() hashCode()
data object MyDataObject {
    val x: Int = 3
}



// 创建实例时首先执行主构造，接着属性初始化器，初始化块根据出现的顺序依次执行
class InitOrderDemo(val name: String) {
    lateinit var vertexCount: String
    // 属性初始化器
    val firstProperty = "First property: $name".also(::println)
    // 初始化块
    init {
        println("First initializer block that prints $name")
    }
    val secondProperty = "Second property: ${name.length}".also(::println)
    init {
        println("Second initializer block that prints ${name.length}")
    }
}

